home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / aplictns / dkbtrace / part04 < prev    next >
Encoding:
Internet Message Format  |  1990-09-03  |  63.2 KB

  1. Path: abcfd20.larc.nasa.gov!amiga-request
  2. From: amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
  3. Subject: v90i252: DKBTrace 2.01 - DKBtrace Ray-Tracer, Part04/10
  4. Reply-To: David Schanen <mtv@milton.u.washington.edu>
  5. Newsgroups: comp.sources.amiga
  6. Message-ID: <comp.sources.amiga:v90i252@abcfd20.larc.nasa.gov>
  7. References: <comp.sources.amiga:v90i249@abcfd20.larc.nasa.gov>
  8. Date: 03 Sep 90 23:21:58 GMT
  9. Approved: tadguy@uunet.UU.NET (Tad Guy)
  10. X-Mail-Submissions-To: amiga@uunet.uu.net
  11. X-Post-Discussions-To: comp.sys.amiga
  12.  
  13. Submitted-by: David Schanen <mtv@milton.u.washington.edu>
  14. Posting-number: Volume 90, Issue 252
  15. Archive-name: applications/dkbtrace-2.01/part04
  16.  
  17. #!/bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 4 (of 10)."
  24. # Contents:  src/DumpToIFF.c src/ibm.c src/iff.c src/objects.c
  25. #   src/quadrics.c
  26. # Wrapped by tadguy@abcfd20 on Mon Sep  3 19:21:18 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'src/DumpToIFF.c' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'src/DumpToIFF.c'\"
  30. else
  31. echo shar: Extracting \"'src/DumpToIFF.c'\" \(13811 characters\)
  32. sed "s/^X//" >'src/DumpToIFF.c' <<'END_OF_FILE'
  33. X/*****************************************************************************
  34. X*
  35. X*                                   dumptoiff.c
  36. X*
  37. X*   from DKBTrace (c) 1990  David Buck
  38. X*
  39. X*  This file converts the raw output from the ray tracer into HAM files.
  40. X*
  41. X* This software is freely distributable. The source and/or object code may be
  42. X* copied or uploaded to communications services so long as this notice remains
  43. X* at the top of each file.  If any changes are made to the program, you must
  44. X* clearly indicate in the documentation and in the programs startup message
  45. X* who it was who made the changes. The documentation should also describe what
  46. X* those changes were. This software may not be included in whole or in
  47. X* part into any commercial package without the express written consent of the
  48. X* author.  It may, however, be included in other public domain or freely
  49. X* distributed software so long as the proper credit for the software is given.
  50. X*
  51. X* This software is provided as is without any guarantees or warranty. Although
  52. X* the author has attempted to find and correct any bugs in the software, he
  53. X* is not responsible for any damage caused by the use of the software.  The
  54. X* author is under no obligation to provide service, corrections, or upgrades
  55. X* to this package.
  56. X*
  57. X* Despite all the legal stuff above, if you do find bugs, I would like to hear
  58. X* about them.  Also, if you have any comments or questions, you may contact me
  59. X* at the following address:
  60. X*
  61. X*     David Buck
  62. X*     22C Sonnet Cres.
  63. X*     Nepean Ontario
  64. X*     Canada, K2H 8W7
  65. X*
  66. X*  I can also be reached on the following bulleton boards:
  67. X*
  68. X*     ATX              (613) 526-4141
  69. X*     OMX              (613) 731-3419
  70. X*     Mystic           (613) 731-0088 or (613) 731-6698
  71. X*
  72. X*  Fidonet:   1:163/109.9
  73. X*  Internet:  David_Buck@Carleton.CA
  74. X*
  75. X*
  76. X*****************************************************************************/
  77. X
  78. X
  79. X#include <stdio.h>
  80. X#include <exec/types.h>
  81. X#include <intuition/intuition.h>
  82. X#include <graphics/display.h>
  83. X#include <libraries/dos.h>
  84. X#include <proto/all.h>
  85. X#include "config.h"
  86. X#include "iff.h"
  87. X#include "dumptoiff.h"
  88. X#include "dumproto.h"
  89. X
  90. Xstruct IntuitionBase *IntuitionBase;
  91. Xstruct GfxBase *GfxBase;
  92. Xstruct Screen *s;
  93. X
  94. X#define extract_red(x) ((x & 0xF00) >> 8)
  95. X#define extract_green(x) ((x & 0x0F0) >> 4)
  96. X#define extract_blue(x) (x & 0x00F)
  97. X
  98. Xstruct NewScreen MyScreen =
  99. X   {
  100. X   0, 0,
  101. X   SCREEN_WIDTH, SCREEN_HEIGHT,
  102. X   6,
  103. X   0, 1,
  104. X   INTERLACE | HAM,
  105. X   0,
  106. X   NULL,
  107. X   (UBYTE *) "DumpToIFF",
  108. X   NULL,
  109. X   NULL
  110. X   };
  111. X
  112. XUWORD ColourTbl[16] = { 0x000, 0x111, 0x222, 0x333, 0x444, 0x555, 0x666,
  113. X                        0x777, 0x888, 0x999, 0xaaa, 0xbbb, 0xccc, 0xddd,
  114. X                        0xeee, 0xfff };
  115. X
  116. XLONG last_y = -1;
  117. XIMAGE Raw_Image;
  118. X
  119. XFILE *fp, *palette_file, *output_palette_file;
  120. Xchar input_filename[100], palette_filename[100], output_filename[100];
  121. Xchar output_palette_filename[100];
  122. X
  123. X
  124. Xint output_file, read_palette, write_palette, dithering;
  125. Xvoid get_parameters(int argc, char **argv);
  126. X
  127. Xvoid main (argc, argv) 
  128. X   int argc;
  129. X   char **argv;
  130. X   {
  131. X   unsigned int red, green, blue, i;
  132. X   unsigned int x, y, index;
  133. X
  134. X   if (argc < 2)
  135. X     {
  136. X     printf ("\nUsage:  DumpToIFF [options] <dump_filename> <iff_file_name> [<palette_filename>]\n");
  137. X     printf ("            Options:\n");
  138. X     printf ("               -d           - No dithering\n");
  139. X     printf ("               -pfilename   - Write a palette file\n");
  140. X     exit(0);
  141. X     }
  142. X
  143. X   Close_Threshold = 5;
  144. X
  145. X   fp = NULL;
  146. X   read_palette = FALSE;
  147. X   write_palette = FALSE;
  148. X   output_file = FALSE;
  149. X   dithering = TRUE;
  150. X
  151. X   IntuitionBase = (struct IntuitionBase *)
  152. X                    OpenLibrary ("intuition.library",INT_REV);
  153. X   if (IntuitionBase == NULL)
  154. X      exit(FALSE);
  155. X
  156. X   GfxBase = (struct GfxBase *)
  157. X                      OpenLibrary ("graphics.library", GR_REV);
  158. X   if (GfxBase == NULL)
  159. X      exit(FALSE);
  160. X
  161. X   get_parameters(argc, argv);
  162. X
  163. X   printf ("Reading raw file\n");
  164. X   read_raw_image (&Raw_Image, input_filename);
  165. X
  166. X
  167. X   if (dithering) {
  168. X      printf ("Dithering...\n");
  169. X      dither(&Raw_Image);
  170. X      }
  171. X
  172. X   printf ("Processing...\n");
  173. X   if (read_palette) {
  174. X      if ((palette_file = fopen (palette_filename, "r")) == NULL) {
  175. X         display_close();
  176. X         exit(FALSE);
  177. X         }
  178. X
  179. X      for (i = 0 ; i < 16 ; i++) {
  180. X         if (fscanf (palette_file, "%d %d %d", &red, &green, &blue) != 3) {
  181. X            printf ("Error reading palette file\n");
  182. X            exit (1);
  183. X            }
  184. X
  185. X         ColourTbl[i] = ((red & 0x0f) << 8) |
  186. X                        ((green & 0x0f) << 4) | (blue & 0x0f);
  187. X         }
  188. X      }
  189. X   else {
  190. X      start_recording_colours();
  191. X
  192. X      for (y = 0 ; y < Raw_Image.height ; y++) {
  193. X         for (x = 0 ; x < Raw_Image.width ; x++) {
  194. X            index = y*Raw_Image.width + x;
  195. X            process (x, y, Raw_Image.red[index],
  196. X                           Raw_Image.green[index],
  197. X                           Raw_Image.blue[index]);
  198. X         
  199. X            }
  200. X         }
  201. X      choose_palette();
  202. X      }
  203. X
  204. X   /* Write out the palette file */
  205. X   if (write_palette) {
  206. X      if ((output_palette_file = fopen (output_palette_filename, "w")) == NULL)
  207. X         {
  208. X         printf ("Cannot create palette file\n");
  209. X         exit (1);
  210. X         }
  211. X
  212. X      
  213. X      for (i = 0 ; i < 16 ; i++)
  214. X         fprintf (output_palette_file, "%d %d %d\n",
  215. X                  extract_red(ColourTbl[i]),
  216. X                  extract_green(ColourTbl[i]),
  217. X                  extract_blue(ColourTbl[i]));
  218. X
  219. X
  220. X      fclose(output_palette_file);
  221. X      }
  222. X
  223. X   printf ("Displaying...\n");
  224. X
  225. X   MyScreen.Width = Raw_Image.width+1;
  226. X   MyScreen.Height = Raw_Image.height;
  227. X   if ((s = (struct Screen *) OpenScreen (&MyScreen))
  228. X          == NULL)
  229. X      exit (FALSE);
  230. X
  231. X   ShowTitle (s, FALSE);
  232. X
  233. X
  234. X   SetAPen (&(s->RastPort), 7L);
  235. X   RectFill (&(s -> RastPort), 0L, 0L, Raw_Image.width, Raw_Image.height-1);
  236. X
  237. X   LoadRGB4 (&(s->ViewPort), ColourTbl, 16L);
  238. X
  239. X   for (y = 0 ; y < Raw_Image.height ; y++) {
  240. X      for (x = 0 ; x < Raw_Image.width ; x++) {
  241. X            index = y*Raw_Image.width + x;
  242. X            display_plot (x, y, Raw_Image.red[index],
  243. X                                Raw_Image.green[index],
  244. X                                Raw_Image.blue[index]);
  245. X         }
  246. X      }
  247. X
  248. X   if (output_file)
  249. X      ConvertToIFF(output_filename);
  250. X
  251. X   printf ("Finished\n");
  252. X   display_close();
  253. X   }
  254. X
  255. Xvoid get_parameters (argc, argv)
  256. X   int argc;
  257. X   char **argv;
  258. X   {
  259. X   int i, filename_number;
  260. X
  261. X   filename_number = 0;
  262. X   for (i = 1 ; i < argc ; i++) {
  263. X      if (argv[i][0] == '-')
  264. X         switch (argv[i][1]) {
  265. X            case 'd':  dithering = FALSE;
  266. X                       break;
  267. X
  268. X            case 'p':  strcpy (output_palette_filename, &argv[i][2]);
  269. X                       write_palette = TRUE;
  270. X                       break;
  271. X
  272. X            default:   printf ("Unknown option\n");
  273. X                       break;
  274. X            }
  275. X      else
  276. X         switch (filename_number) {
  277. X            case 0: strcpy (input_filename, argv[i]);
  278. X                    filename_number++;
  279. X                    break;
  280. X
  281. X            case 1: strcpy (output_filename, argv[i]);
  282. X                    output_file = TRUE;
  283. X                    filename_number++;
  284. X                    break;
  285. X
  286. X            case 2: strcpy (palette_filename, argv[i]);
  287. X                    filename_number++;
  288. X                    read_palette = TRUE;
  289. X                    break;
  290. X
  291. X            default: printf ("Too many filenames in commandline\n");
  292. X                     exit(1);
  293. X            }
  294. X      }
  295. X   if (filename_number == 0) {
  296. X      printf ("No input file specified\n");
  297. X      exit(1);
  298. X      }
  299. X   }
  300. X
  301. X
  302. Xvoid display_close ()
  303. X   {
  304. X   if (fp != NULL)
  305. X      fclose (fp);
  306. X   CloseScreen (s);
  307. X   CloseLibrary (GfxBase) ;
  308. X   CloseLibrary (IntuitionBase) ;
  309. X   }
  310. X
  311. Xvoid display_plot (x, y, new_red, new_green, new_blue)
  312. X   LONG x, y, new_red, new_green, new_blue;
  313. X   {
  314. X   LONG colour, newline;
  315. X
  316. X   new_red &= 0xFF;
  317. X   new_green &= 0xFF;
  318. X   new_blue &= 0xFF;
  319. X
  320. X   new_red /= 16;
  321. X   new_green /= 16;
  322. X   new_blue /= 16;
  323. X
  324. X   newline = 0;
  325. X   if (last_y != y) {
  326. X      newline = 1;
  327. X      last_y = y;
  328. X      reset_colours();
  329. X      SetAPen (&(s -> RastPort), 0);
  330. X      WritePixel (&(s -> RastPort), 0, y);
  331. X      }
  332. X
  333. X   colour = best_colour (new_red, new_blue, new_green);
  334. X   SetAPen (&(s -> RastPort), colour);
  335. X   WritePixel (&(s -> RastPort), x+1, y);
  336. X   }
  337. X
  338. X
  339. Xvoid dither (Image)
  340. X   IMAGE *Image;
  341. X   {
  342. X   long index;
  343. X   short i, j, new_red, new_green, new_blue,
  344. X       red_error, green_error, blue_error;
  345. X
  346. X   red_error = 0;
  347. X   green_error = 0;
  348. X   blue_error = 0;
  349. X
  350. X   for (j = 0 ; j < Image->height ; j++)
  351. X      for (i = 0 ; i < Image->width ; i++) {
  352. X         index = j * Image->width + i;
  353. X         red_error = Image->red[index] % 16;
  354. X         green_error = Image->green[index] % 16;
  355. X         blue_error = Image->blue[index] % 16;
  356. X
  357. X         if (i < Image->width-1) {
  358. X            new_red = Image->red[index+1] + red_error * 7 / 16;
  359. X            new_green = Image->green[index+1] + green_error * 7 / 16;
  360. X            new_blue = Image->blue[index+1] + blue_error * 7 / 16;
  361. X            Image->red[index+1] = (new_red>255) ? 255 : new_red;
  362. X            Image->green[index+1] = (new_green>255) ? 255 : new_green;
  363. X            Image->blue[index+1] = (new_blue>255) ? 255 : new_blue;
  364. X            }
  365. X
  366. X         if (j < Image->height-1) {
  367. X            index += Image->width;
  368. X            if (i != 0) {
  369. X               new_red = Image->red[index-1] + red_error * 3 / 16;
  370. X               new_green = Image->green[index-1] + green_error * 3 / 16;
  371. X               new_blue = Image->blue[index-1] + blue_error * 3 / 16;
  372. X               Image->red[index-1] = (new_red>255) ? 255 : new_red;
  373. X               Image->green[index-1] = (new_green>255) ? 255 : new_green;
  374. X               Image->blue[index-1] = (new_blue>255) ? 255 : new_blue;
  375. X               }
  376. X
  377. X
  378. X            new_red = Image->red[index] + red_error * 5 / 16;
  379. X            new_green = Image->green[index] + green_error * 5 / 16;
  380. X            new_blue = Image->blue[index] + blue_error * 5 / 16;
  381. X            Image->red[index] = (new_red>255) ? 255 : new_red;
  382. X            Image->green[index] = (new_green>255) ? 255 : new_green;
  383. X            Image->blue[index] = (new_blue>255) ? 255 : new_blue;
  384. X
  385. X            if (i < Image->width-1) {
  386. X               new_red = Image->red[index+1] + red_error / 16;
  387. X               new_green = Image->green[index+1] + green_error / 16;
  388. X               new_blue = Image->blue[index+1] + blue_error / 16;
  389. X               Image->red[index+1] = (new_red>255) ? 255 : new_red;
  390. X               Image->green[index+1] = (new_green>255) ? 255 : new_green;
  391. X               Image->blue[index+1] = (new_blue>255) ? 255 : new_blue;
  392. X               }
  393. X            }
  394. X         }
  395. X   }
  396. X
  397. X
  398. Xvoid process (x, y, new_red, new_green, new_blue)
  399. X   LONG x, y, new_red, new_green, new_blue;
  400. X   {
  401. X   LONG newline;
  402. X
  403. X   new_red &= 0xFF;
  404. X   new_green &= 0xFF;
  405. X   new_blue &= 0xFF;
  406. X
  407. X   new_red /= 16;
  408. X   new_green /= 16;
  409. X   new_blue /= 16;
  410. X
  411. X   newline = 0;
  412. X   if (last_y != y) {
  413. X     newline = 1;
  414. X     last_y = y;
  415. X     reset_colours();
  416. X     }
  417. X
  418. X   record_colours (new_red, new_green, new_blue);
  419. X   }
  420. X
  421. X
  422. Xvoid ConvertToIFF(file_name)
  423. X   char *file_name;
  424. X   {
  425. X   char *buffer;
  426. X   BPTR file;
  427. X   BOOL PutPict();
  428. X
  429. X   if ((file = Open (file_name, MODE_NEWFILE)) == 0) {
  430. X      printf ("\nCannot open IFF file\n");
  431. X      exit (0);
  432. X      }
  433. X
  434. X   buffer = malloc(BUFFER_SIZE);
  435. X   if (PutPict (file, &(s->ViewPort), buffer, BUFFER_SIZE))
  436. X      printf ("\nIFF write error\n");
  437. X   Close (file);
  438. X   }
  439. X
  440. Xint read_raw_byte(f)
  441. X   FILE *f;
  442. X   {
  443. X   int c;
  444. X   if ((c = getc(f)) == EOF)
  445. X      return (-1);
  446. X   return (c);
  447. X   }
  448. X
  449. Xint read_raw_word(f)
  450. X   FILE *f;
  451. X   {
  452. X   int byte1, byte2;
  453. X
  454. X   byte1 = read_raw_byte(f);
  455. X   if (byte1 == -1)
  456. X      return(-1);
  457. X
  458. X   byte2 = read_raw_byte(f);
  459. X   if (byte2 == -1)
  460. X      return(-1);
  461. X
  462. X   return (byte1 + byte2*256);
  463. X   }
  464. X
  465. Xvoid read_raw_image(Image, filename)
  466. X   IMAGE *Image;
  467. X   char *filename;
  468. X   {
  469. X   FILE *f;
  470. X   int byte, i, index, row, pixels;
  471. X
  472. X   if ((f = fopen(filename, "rb")) == NULL) {
  473. X      printf ("Cannot open raw file %s\n", filename);
  474. X      exit(1);
  475. X      }
  476. X
  477. X   Image->width = read_raw_word(f);
  478. X   if (Image->width == -1) {
  479. X      printf ("Cannot read size in dump file\n");
  480. X      exit(1);
  481. X      }
  482. X
  483. X   Image->height = read_raw_word(f);
  484. X   if (Image->height == -1) {
  485. X      printf ("Cannot read size in dump file: %s\n", filename);
  486. X      exit(1);
  487. X      }
  488. X
  489. X   pixels = Image->width * Image->height;
  490. X
  491. X   if (((Image->red = (unsigned char *) malloc(pixels))==NULL) ||
  492. X       ((Image->green = (unsigned char *) malloc(pixels))==NULL) ||
  493. X       ((Image->blue = (unsigned char *) malloc(pixels))==NULL)) {
  494. X      printf ("Cannot allocate memory for picture: %s\n", filename);
  495. X      exit(1);
  496. X      }
  497. X
  498. X   for (i = 0 ; i < pixels ; i++) {
  499. X      Image->red[i] = 0;
  500. X      Image->green[i] = 0;
  501. X      Image->blue[i] = 0;
  502. X      }
  503. X
  504. X   row = read_raw_word(f);
  505. X   while (row != -1) {
  506. X      for (i = 0 ; i < Image->width ; i++) {
  507. X         index = row*Image->width + i;
  508. X
  509. X         byte = read_raw_byte(f);
  510. X         if (byte == -1) {
  511. X            printf ("Unexpected end of file in raw image: %s\n", filename);
  512. X            exit(1);
  513. X            }
  514. X         Image->red[index] = byte;
  515. X         }
  516. X
  517. X      for (i = 0 ; i < Image->width ; i++) {
  518. X         index = row*Image->width + i;
  519. X
  520. X         byte = read_raw_byte(f);
  521. X         if (byte == -1) {
  522. X            printf ("Unexpected end of file in raw image: %s\n", filename);
  523. X            exit(1);
  524. X            }
  525. X         Image->green[index] = byte;
  526. X         }
  527. X
  528. X      for (i = 0 ; i < Image->width ; i++) {
  529. X         index = row*Image->width + i;
  530. X
  531. X         byte = read_raw_byte(f);
  532. X         if (byte == -1) {
  533. X            printf ("Unexpected end of file in raw image: %s\n", filename);
  534. X            exit(1);
  535. X            }
  536. X         Image->blue[index] = byte;
  537. X         }
  538. X      row = read_raw_word(f);
  539. X      }
  540. X   fclose (f);
  541. X   }
  542. END_OF_FILE
  543. if test 13811 -ne `wc -c <'src/DumpToIFF.c'`; then
  544.     echo shar: \"'src/DumpToIFF.c'\" unpacked with wrong size!
  545. fi
  546. # end of 'src/DumpToIFF.c'
  547. fi
  548. if test -f 'src/ibm.c' -a "${1}" != "-c" ; then 
  549.   echo shar: Will not clobber existing file \"'src/ibm.c'\"
  550. else
  551. echo shar: Extracting \"'src/ibm.c'\" \(10840 characters\)
  552. sed "s/^X//" >'src/ibm.c' <<'END_OF_FILE'
  553. X/*****************************************************************************
  554. X*
  555. X*                                      ibm.c
  556. X*
  557. X*   from DKBTrace (c) 1990  David Buck
  558. X*
  559. X*  This module implements the IBM-specific routines for DKBTrace.
  560. X*
  561. X* This software is freely distributable. The source and/or object code may be
  562. X* copied or uploaded to communications services so long as this notice remains
  563. X* at the top of each file.  If any changes are made to the program, you must
  564. X* clearly indicate in the documentation and in the programs startup message
  565. X* who it was who made the changes. The documentation should also describe what
  566. X* those changes were. This software may not be included in whole or in
  567. X* part into any commercial package without the express written consent of the
  568. X* author.  It may, however, be included in other public domain or freely
  569. X* distributed software so long as the proper credit for the software is given.
  570. X*
  571. X* This software is provided as is without any guarantees or warranty. Although
  572. X* the author has attempted to find and correct any bugs in the software, he
  573. X* is not responsible for any damage caused by the use of the software.  The
  574. X* author is under no obligation to provide service, corrections, or upgrades
  575. X* to this package.
  576. X*
  577. X* Despite all the legal stuff above, if you do find bugs, I would like to hear
  578. X* about them.  Also, if you have any comments or questions, you may contact me
  579. X* at the following address:
  580. X*
  581. X*     David Buck
  582. X*     22C Sonnet Cres.
  583. X*     Nepean Ontario
  584. X*     Canada, K2H 8W7
  585. X*
  586. X*  I can also be reached on the following bulleton boards:
  587. X*
  588. X*     ATX              (613) 526-4141
  589. X*     OMX              (613) 731-3419
  590. X*     Mystic           (613) 731-0088 or (613) 731-6698
  591. X*
  592. X*  Fidonet:   1:163/109.9
  593. X*  Internet:  David_Buck@Carleton.CA
  594. X*
  595. X*  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  596. X*
  597. X*     Lattice BBS                      (708) 916-1200
  598. X*     The Information Exchange BBS     (708) 945-5575
  599. X*     Stillwaters BBS                  (708) 403-2826
  600. X*
  601. X*****************************************************************************/
  602. X
  603. X#include "frame.h"
  604. X#include "dkbproto.h"
  605. X
  606. X/* IBM VGA "colour" output routines for MS/DOS by Aaron A. Collins.  This
  607. X   will deliver approximate colorings using HSV values for the approximation.
  608. X   The pallette map is divided into 4 parts - upper and lower half generated
  609. X   with full and half "value" (intensity), respectively.  These halves are
  610. X   further halved by full and half saturation values of each range (pastels).
  611. X   There are three constant colors, black, white, and grey.  They are used
  612. X   when the saturation is low enough that the hue becomes undefined, and which
  613. X   one is selected is based on a simple range map of "value".  Usage of the
  614. X   pallette is accomplished by converting the requested color RGB into an HSV
  615. X   value.  If the saturation is too low (< .25) then black, white or grey is
  616. X   selected.  If there is enough saturation to consider looking at the hue,
  617. X   then the hue range of 1-63 is scaled into one of the 4 pallette quadrants
  618. X   based on its "value" and "saturation" characteristics.
  619. X*/
  620. X
  621. X#include <dos.h>    /* MS-DOS specific - for int86() REGS struct, etc. */
  622. X
  623. Xvoid set_pallette_register(unsigned, unsigned, unsigned, unsigned);
  624. Xvoid hsv_to_rgb(DBL, DBL, DBL, unsigned *, unsigned *, unsigned *);
  625. Xvoid rgb_to_hsv(unsigned, unsigned, unsigned, DBL *, DBL *, DBL *);
  626. X
  627. Xextern unsigned _stklen = 32768U;   /* HUGE stack for HEAVY recursion */
  628. Xextern int Options;
  629. X
  630. Xvoid display_init()
  631. X   {
  632. X   union REGS inr, outr;
  633. X   register unsigned m;
  634. X   unsigned r, g, b;
  635. X   register DBL hue, sat, val;
  636. X
  637. X   inr.x.ax = 0x0013;           /* setup to VGA 320x200x256 (mode 13H) */
  638. X   int86(0x10, &inr, &outr);
  639. X
  640. X   inr.x.ax = 0x1010;           /* make pallette register 0 black */
  641. X   inr.x.bx = 0;
  642. X   inr.h.ch = inr.h.cl = inr.h.dh = 0;   /* full off */
  643. X   int86(0x10, &inr, &outr);
  644. X
  645. X   inr.x.ax = 0x1010;           /* make pallette register 64 white */
  646. X   inr.x.bx = 64;
  647. X   inr.h.ch = inr.h.cl = inr.h.dh = 63;  /* full on */
  648. X   int86(0x10, &inr, &outr);
  649. X
  650. X   inr.x.ax = 0x1010;           /* make pallette register 128 dark grey */
  651. X   inr.x.bx = 128;
  652. X   inr.h.ch = inr.h.cl = inr.h.dh = 31;  /* half on (dark grey) */
  653. X   int86(0x10, &inr, &outr);
  654. X
  655. X   inr.x.ax = 0x1010;           /* make pallette register 192 lite grey */
  656. X   inr.x.bx = 192;
  657. X   inr.h.ch = inr.h.cl = inr.h.dh = 48;  /* 3/4 on (lite grey) */
  658. X   int86(0x10, &inr, &outr);
  659. X
  660. X   for (m = 1; m < 64; m++)     /* for the 1st 64 colors... */
  661. X      {
  662. X      sat = 0.5;                /* start with the saturation and intensity low */
  663. X      val = 0.5;
  664. X      hue = 360.0 * ((DBL)(m)) / 64.0;   /* normalize to 360 */
  665. X      hsv_to_rgb (hue, sat, val, &r, &g, &b);
  666. X      set_pallette_register (m, r, g, b); /* set m to rgb value */
  667. X
  668. X      sat = 1.0;                /* high saturation and half intensity (shades) */
  669. X      val = 0.50;
  670. X      hue = 360.0 * ((DBL)(m)) / 64.0;   /* normalize to 360 */
  671. X      hsv_to_rgb (hue, sat, val, &r, &g, &b);
  672. X      set_pallette_register (m + 64, r, g, b);  /* set m + 64 */
  673. X
  674. X      sat = 0.5;                /* half saturation and high intensity (pastels) */
  675. X      val = 1.0;
  676. X
  677. X      hue = 360.0 * ((DBL)(m)) / 64.0;   /* normalize to 360 */
  678. X      hsv_to_rgb (hue, sat, val, &r, &g, &b);
  679. X      set_pallette_register (m + 128, r, g, b); /* set m + 128 */
  680. X
  681. X      sat = 1.0;                /* normal full HSV set at full intensity */
  682. X      val = 1.0;
  683. X   
  684. X      hue = 360.0 * ((DBL)(m)) / 64.0;   /* normalize to 360 */
  685. X      hsv_to_rgb (hue, sat, val, &r, &g, &b);
  686. X      set_pallette_register (m + 192, r, g, b); /* set m + 192 */
  687. X      }
  688. X   return;
  689. X   }
  690. X
  691. Xvoid display_finished ()
  692. X   {
  693. X   if (Options & PROMPTEXIT)
  694. X      {
  695. X      printf ("\007\007");   /* long beep */
  696. X      getch();
  697. X      }
  698. X   }
  699. X
  700. Xvoid display_close()   /* setup to Text 80x25 (mode 3) */
  701. X   {
  702. X   union REGS inr, outr;
  703. X
  704. X   inr.x.ax = 0x0003;
  705. X   int86(0x10, &inr, &outr);
  706. X   return;
  707. X   }
  708. X
  709. Xvoid display_plot (x, y, Red, Green, Blue)   /* plot a single RGB pixel */
  710. X   int x, y;
  711. X   char Red, Green, Blue;
  712. X   {
  713. X   register unsigned char color;
  714. X   unsigned char far *fp;
  715. X   DBL h, s, v;
  716. X
  717. X   /* Translate RGB value to best of 256 pallete Colors (by HSV?) */
  718. X
  719. X   rgb_to_hsv((unsigned)Red,(unsigned)Green,(unsigned)Blue, &h, &s, &v);
  720. X
  721. X   if (s < 0.25)   /* black or white if no saturation of color... */
  722. X      {
  723. X      if (v < 0.25)
  724. X         color = 0;        /* black */
  725. X      else if (v > 0.75)
  726. X         color = 64;       /* white */
  727. X      else if (v > 0.5)
  728. X         color = 192;      /* lite grey */
  729. X      else
  730. X         color = 128;      /* dark grey */
  731. X      }
  732. X   else
  733. X      {
  734. X      color = (unsigned char) (64.0 * ((DBL)(h)) / 360.0);
  735. X
  736. X      if (!color)
  737. X         color = 1;        /* avoid black, white or grey */
  738. X      
  739. X      if (color > 63)
  740. X         color = 63;       /* avoid same */
  741. X
  742. X      if (v > 0.50)
  743. X         color |= 0x80;    /* colors 128-255 for high inten. */
  744. X
  745. X      if (s > 0.50)        /* more than half saturated? */
  746. X         color |= 0x40;    /* color range 64-128 or 192-255 */
  747. X      }
  748. X
  749. X   fp = MK_FP(0xa000, 320 * y + x);
  750. X
  751. X   *fp = color;            /* normalize color to 256 */
  752. X
  753. X   return;
  754. X   }
  755. X
  756. Xvoid set_pallette_register (Val, Red, Green, Blue)
  757. X   unsigned Val;
  758. X   unsigned Red, Green, Blue;
  759. X   {
  760. X   union REGS Regs;
  761. X
  762. X   Regs.x.ax = 0x1010;              /* Set one pallette register function */
  763. X   Regs.x.bx = Val;                 /* the pallette register to set (color #) */
  764. X   Regs.h.dh = (char) Red & 0xff;   /* set the gun values (6 bits ea.) */
  765. X   Regs.h.ch = (char) Green & 0xff;
  766. X   Regs.h.cl = (char) Blue & 0xff;
  767. X   int86(0x10, &Regs, &Regs);       /* Do the video interrupt */
  768. X   }
  769. X
  770. X/* Conversion from Hue, Saturation, Value to Red, Green, and Blue and back */
  771. X/* From "Computer Graphics", Donald Hearn & M. Pauline Baker, p. 304 */
  772. X
  773. Xvoid hsv_to_rgb(hue, s, v, r, g, b)
  774. X   DBL hue, s, v;               /* hue (0.0 to 360.0) s and v are from 0.0 - 1.0) */
  775. X   unsigned *r, *g, *b;         /* values from 0 to 63 */
  776. X   {
  777. X   register DBL i, f, p1, p2, p3;
  778. X   register DBL xh;
  779. X   register DBL nr, ng, nb;     /* rgb values of 0.0 - 1.0      */
  780. X
  781. X   if (hue == 360.0)
  782. X      hue = 0.0;                /* (THIS LOOKS BACKWARDS BUT OK) */
  783. X
  784. X   xh = hue / 60.0;             /* convert hue to be in 0,6     */
  785. X   i = floor(xh);               /* i = greatest integer <= h    */
  786. X   f = xh - i;                  /* f = fractional part of h     */
  787. X   p1 = v * (1 - s);
  788. X   p2 = v * (1 - (s * f));
  789. X   p3 = v * (1 - (s * (1 - f)));
  790. X
  791. X   switch ((int) i)
  792. X      {
  793. X      case 0:
  794. X         nr = v;
  795. X         ng = p3;
  796. X         nb = p1;
  797. X         break;
  798. X      case 1:
  799. X         nr = p2;
  800. X         ng = v;
  801. X         nb = p1;
  802. X         break;
  803. X      case 2:
  804. X         nr = p1;
  805. X         ng = v;
  806. X         nb = p3;
  807. X         break;
  808. X      case 3:
  809. X         nr = p1;
  810. X         ng = p2;
  811. X         nb = v;
  812. X         break;
  813. X      case 4:
  814. X         nr = p3;
  815. X         ng = p1;
  816. X         nb = v;
  817. X         break;
  818. X      case 5:
  819. X         nr = v;
  820. X         ng = p1;
  821. X         nb = p2;
  822. X         break;
  823. X        }
  824. X
  825. X   *r = (unsigned)(nr * 63.0); /* Normalize the values to 63 */
  826. X   *g = (unsigned)(ng * 63.0);
  827. X   *b = (unsigned)(nb * 63.0);
  828. X   
  829. X   return;
  830. X   }
  831. X
  832. Xvoid rgb_to_hsv(r, g, b, h, s, v)
  833. X   unsigned r, g, b;
  834. X   DBL *h, *s, *v;
  835. X   {
  836. X   register DBL m, r1, g1, b1;
  837. X   register DBL nr, ng, nb;      /* rgb values of 0.0 - 1.0      */
  838. X   register DBL nh, ns, nv;      /* hsv local values */
  839. X
  840. X   nr = (DBL) r / 255.0;
  841. X   ng = (DBL) g / 255.0;
  842. X   nb = (DBL) b / 255.0;
  843. X
  844. X   nv = max (nr, max (ng, nb));
  845. X   m = min (nr, min (ng, nb));
  846. X
  847. X   if (nv != 0.0)                /* if no value, it's black! */
  848. X      ns = (nv - m) / nv;
  849. X   else
  850. X      ns = 0.0;                 /* black = no colour saturation */
  851. X
  852. X   if (ns == 0.0)                /* hue undefined if no saturation */
  853. X   {
  854. X      *h = 0.0;                  /* return black level (?) */
  855. X      *s = 0.0;
  856. X      *v = nv;
  857. X      return;
  858. X   }
  859. X
  860. X   r1 = (nv - nr) / (nv - m);    /* distance of color from red   */
  861. X   g1 = (nv - ng) / (nv - m);    /* distance of color from green   */
  862. X   b1 = (nv - nb) / (nv - m);    /* distance of color from blue   */
  863. X
  864. X   if (nv == nr)
  865. X   {
  866. X      if (m == ng)
  867. X         nh = 5. + b1;
  868. X      else
  869. X         nh = 1. - g1;
  870. X   } 
  871. X
  872. X   if (nv == ng)
  873. X      {
  874. X      if (m == nb)
  875. X         nh = 1. + r1;
  876. X      else
  877. X         nh = 3. - b1;
  878. X      }
  879. X
  880. X   if (nv == nb)
  881. X      {
  882. X      if (m == nr)
  883. X         nh = 3. + g1;
  884. X      else
  885. X         nh = 5. - r1;
  886. X      }
  887. X
  888. X   *h = nh * 60.0;      /* return h converted to degrees */
  889. X   *s = ns;
  890. X   *v = nv;
  891. X   return;
  892. X   }
  893. X
  894. X#if !__STDC__
  895. X
  896. X/* ANSI Standard random number generator */
  897. X
  898. Xstatic unsigned long int next = 1;
  899. X
  900. Xint rand()
  901. X   {
  902. X   next = next * 1103515245L + 12345L;
  903. X   return ((int) (next / 0x10000L) & 0x7FFF);
  904. X   }
  905. X
  906. Xvoid srand(seed)
  907. X   unsigned int seed;
  908. X   {
  909. X   next = seed;
  910. X   }
  911. X
  912. X#endif
  913. END_OF_FILE
  914. if test 10840 -ne `wc -c <'src/ibm.c'`; then
  915.     echo shar: \"'src/ibm.c'\" unpacked with wrong size!
  916. fi
  917. # end of 'src/ibm.c'
  918. fi
  919. if test -f 'src/iff.c' -a "${1}" != "-c" ; then 
  920.   echo shar: Will not clobber existing file \"'src/iff.c'\"
  921. else
  922. echo shar: Extracting \"'src/iff.c'\" \(10876 characters\)
  923. sed "s/^X//" >'src/iff.c' <<'END_OF_FILE'
  924. X/*****************************************************************************
  925. X*
  926. X*                                     iff.c
  927. X*
  928. X*   from DKBTrace (c) 1990  David Buck
  929. X*
  930. X*  This file implements a simple IFF format file reader.
  931. X*
  932. X* This software is freely distributable. The source and/or object code may be
  933. X* copied or uploaded to communications services so long as this notice remains
  934. X* at the top of each file.  If any changes are made to the program, you must
  935. X* clearly indicate in the documentation and in the programs startup message
  936. X* who it was who made the changes. The documentation should also describe what
  937. X* those changes were. This software may not be included in whole or in
  938. X* part into any commercial package without the express written consent of the
  939. X* author.  It may, however, be included in other public domain or freely
  940. X* distributed software so long as the proper credit for the software is given.
  941. X*
  942. X* This software is provided as is without any guarantees or warranty. Although
  943. X* the author has attempted to find and correct any bugs in the software, he
  944. X* is not responsible for any damage caused by the use of the software.  The
  945. X* author is under no obligation to provide service, corrections, or upgrades
  946. X* to this package.
  947. X*
  948. X* Despite all the legal stuff above, if you do find bugs, I would like to hear
  949. X* about them.  Also, if you have any comments or questions, you may contact me
  950. X* at the following address:
  951. X*
  952. X*     David Buck
  953. X*     22C Sonnet Cres.
  954. X*     Nepean Ontario
  955. X*     Canada, K2H 8W7
  956. X*
  957. X*  I can also be reached on the following bulleton boards:
  958. X*
  959. X*     ATX              (613) 526-4141
  960. X*     OMX              (613) 731-3419
  961. X*     Mystic           (613) 731-0088 or (613) 731-6698
  962. X*
  963. X*  Fidonet:   1:163/109.9
  964. X*  Internet:  David_Buck@Carleton.CA
  965. X*
  966. X*  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  967. X*
  968. X*     Lattice BBS                      (708) 916-1200
  969. X*     The Information Exchange BBS     (708) 945-5575
  970. X*     Stillwaters BBS                  (708) 403-2826
  971. X*
  972. X*****************************************************************************/
  973. X
  974. X
  975. X#include "frame.h"
  976. X#include "dkbproto.h"
  977. X
  978. Xstatic IMAGE_COLOUR *iff_colour_map;
  979. Xstatic int colourmap_size;
  980. Xstatic CHUNK_HEADER Chunk_Header;
  981. X
  982. X#define FORM 0x464f524dL
  983. X#define ILBM 0x494c424dL
  984. X#define BMHD 0x424d4844L
  985. X#define CAMG 0x43414d47L
  986. X#define CMAP 0x434d4150L
  987. X#define BODY 0x424f4459L
  988. X#define CMPNONE 0
  989. X
  990. X#define HAM 0x800
  991. X
  992. Xvoid iff_error ()
  993. X   {
  994. X   printf ("Invalid iff file\n");
  995. X   exit(1);
  996. X   }
  997. X
  998. Xint read_byte(f)
  999. X   FILE *f;
  1000. X   {
  1001. X   int c;
  1002. X   if ((c = getc(f)) == EOF)
  1003. X      iff_error();
  1004. X   return (c);
  1005. X   }
  1006. X
  1007. Xint read_word(f)
  1008. X   FILE *f;
  1009. X   {
  1010. X   int result;
  1011. X
  1012. X   result = read_byte(f)*256;
  1013. X   result += read_byte(f);
  1014. X   return (result);
  1015. X   }
  1016. X
  1017. Xlong read_long(f)
  1018. X   FILE *f;
  1019. X   {
  1020. X   int i;
  1021. X   long result;
  1022. X
  1023. X   result = 0;
  1024. X   for (i = 0 ; i < 4 ; i++)
  1025. X      result = result * 256 + read_byte(f);
  1026. X
  1027. X   return (result);
  1028. X   }
  1029. X
  1030. Xvoid Read_Chunk_Header (f, dest)
  1031. X   FILE *f;
  1032. X   CHUNK_HEADER *dest;
  1033. X   {
  1034. X   dest->name = read_long(f);
  1035. X   dest->size = read_long(f);
  1036. X   }
  1037. X
  1038. Xvoid read_iff_image(Image, filename)
  1039. X   IMAGE *Image;
  1040. X   char *filename;
  1041. X   {
  1042. X   FILE *f;
  1043. X   unsigned char **row_bytes;
  1044. X   int c, i, j, k, creg, index, nBytes, nBytesRead, nPlanes, compression,
  1045. X       mask, byte_index, count, viewmodes;
  1046. X   int Previous_Red, Previous_Green, Previous_Blue;
  1047. X
  1048. X   if ((f = fopen(filename, "rb")) == NULL) {
  1049. X      printf ("Cannot open IFF file %s\n", filename);
  1050. X      exit(1);
  1051. X      }
  1052. X
  1053. X   Previous_Red = Previous_Green = Previous_Blue = 0;
  1054. X
  1055. X   viewmodes = 0;
  1056. X
  1057. X   while (1) {
  1058. X      Read_Chunk_Header(f, &Chunk_Header);
  1059. X      switch ((int) Chunk_Header.name) {
  1060. X         case FORM:  if (read_long(f) != ILBM)
  1061. X                        iff_error();
  1062. X                     break;
  1063. X
  1064. X         case BMHD:  Image->iwidth = read_word(f);
  1065. X                     Image->width = (DBL)Image->iwidth;
  1066. X                     Image->iheight = read_word(f);
  1067. X                     Image->height = (DBL)Image->iheight;
  1068. X                     read_word(f);  /* x position ignored */
  1069. X                     read_word(f);  /* y position ignored */
  1070. X                     nPlanes = read_byte(f);
  1071. X                     colourmap_size = 1<<nPlanes;
  1072. X                     read_byte(f);   /* masking ignored */
  1073. X                     compression = read_byte(f);   /* masking ignored */
  1074. X                     read_byte(f);   /* pad */
  1075. X                     read_word(f);   /* Transparent colour ignored */
  1076. X                     read_word(f);   /* Aspect ratio ignored */
  1077. X                     read_word(f);   /* page width ignored */
  1078. X                     read_word(f);   /* page height ignored */
  1079. X                     break;
  1080. X
  1081. X         case CAMG:  viewmodes = (int) read_long(f);   /* Viewmodes */
  1082. X                     if (viewmodes & HAM)
  1083. X                        colourmap_size = 16;
  1084. X                     break;
  1085. X
  1086. X         case CMAP:  colourmap_size = (int) Chunk_Header.size / 3;
  1087. X
  1088. X                     if ((iff_colour_map = (IMAGE_COLOUR *) malloc(sizeof(IMAGE_COLOUR)*colourmap_size)) == NULL)
  1089. X                        iff_error();
  1090. X
  1091. X                     for (i = 0 ; i < colourmap_size ; i++) {
  1092. X                        iff_colour_map[i].Red = read_byte(f);
  1093. X                        iff_colour_map[i].Green = read_byte(f);
  1094. X                        iff_colour_map[i].Blue = read_byte(f);
  1095. X                        }
  1096. X                     Previous_Red = iff_colour_map[0].Red;
  1097. X                     Previous_Green = iff_colour_map[0].Green;
  1098. X                     Previous_Blue = iff_colour_map[0].Blue;
  1099. X                     for (i = colourmap_size*3 ; i < Chunk_Header.size ; i++)
  1100. X                        read_byte(f);
  1101. X                     break;
  1102. X
  1103. X         case BODY:  if ((row_bytes = (unsigned char **) malloc (4*nPlanes)) == NULL) {
  1104. X                        printf ("Not enough memory\n");
  1105. X                        exit(1);
  1106. X                        }
  1107. X
  1108. X                     for (i = 0 ; i < nPlanes ; i++)
  1109. X                        if ((row_bytes[i] = (unsigned char *) malloc((Image->iwidth+7)/8)) == NULL) {
  1110. X                           printf ("Not enough memory\n");
  1111. X                           exit(1);
  1112. X                        }
  1113. X
  1114. X                     if (((Image->red = (unsigned char *) malloc(Image->iwidth*Image->iheight))==NULL) ||
  1115. X                         ((Image->green = (unsigned char *) malloc(Image->iwidth*Image->iheight))==NULL) ||
  1116. X                         ((Image->blue = (unsigned char *) malloc(Image->iwidth*Image->iheight))==NULL)) {
  1117. X                        printf ("Cannot allocate memory for picture\n");
  1118. X                        exit(1);
  1119. X                        }
  1120. X
  1121. X                     for (i = 0 ; i < Image->iheight ; i++) {
  1122. X                        for (j = 0 ; j < nPlanes ; j++)
  1123. X                           if (compression == CMPNONE) {
  1124. X                              for (k = 0 ; k < (Image->iwidth+7)/8 ; k++)
  1125. X                                 row_bytes[j][k] = read_byte(f);
  1126. X                           if ((Image->iwidth & 7) != 0)
  1127. X                              read_byte(f);
  1128. X                           }
  1129. X                        else {
  1130. X                           nBytes = 0;
  1131. X                           nBytesRead = 0;
  1132. X                           while (nBytes != (Image->iwidth+7)/8) {
  1133. X                              c = read_byte(f);
  1134. X                              nBytesRead++;
  1135. X                              if ((c >= 0) && (c <= 127))
  1136. X                                 for (k = 0 ; k <= c ; k++)
  1137. X                                    row_bytes[j][nBytes++] = read_byte(f);
  1138. X                              else if ((c >= 129) && (c <= 255)) {
  1139. X                                 count = 257-c;
  1140. X                                 c = read_byte(f);
  1141. X                                 nBytesRead++;
  1142. X                                 for (k = 0 ; k < count ; k++)
  1143. X                                    row_bytes[j][nBytes++] = c;
  1144. X                                 }
  1145. X                              }
  1146. X                             }
  1147. X
  1148. X                        mask = 0x80;
  1149. X                        byte_index = 0;
  1150. X                        for (j = 0 ; j < Image->iwidth ; j++) {
  1151. X                           creg = 0;
  1152. X                           for (k = nPlanes-1 ; k >= 0 ; k--)
  1153. X                              if (row_bytes[k][byte_index] & mask)
  1154. X                                creg = creg*2 + 1;
  1155. X                              else
  1156. X                                creg *= 2;
  1157. X
  1158. X                           index = (Image->iheight-i-1)*Image->iwidth + j;
  1159. X
  1160. X                           if (viewmodes & HAM) {
  1161. X                              switch (creg >> 4) {
  1162. X                                 case 0:
  1163. X                                    Previous_Red = Image->red[index] = iff_colour_map[creg].Red;
  1164. X                                    Previous_Green = Image->green[index] = iff_colour_map[creg].Green;
  1165. X                                    Previous_Blue = Image->blue[index] = iff_colour_map[creg].Blue;
  1166. X                                    break;
  1167. X
  1168. X                                 case 1:
  1169. X                                    Image->red[index] = Previous_Red;
  1170. X                                    Image->green[index] = Previous_Green;
  1171. X                                    Previous_Blue = Image->blue[index] = ((creg & 0xf)<<4) + (creg&0xf);
  1172. X                                    break;
  1173. X
  1174. X                                 case 2:
  1175. X                                    Previous_Red = Image->red[index] = ((creg & 0xf)<<4) + (creg&0xf);
  1176. X                                    Image->green[index] = Previous_Green;
  1177. X                                    Image->blue[index] = Previous_Blue;
  1178. X                                    break;
  1179. X
  1180. X                                 case 3:
  1181. X                                    Image->red[index] = Previous_Red;
  1182. X                                    Previous_Green = Image->green[index] = ((creg & 0xf)<<4) + (creg&0xf);
  1183. X                                    Image->blue[index] = Previous_Blue;
  1184. X                                    break;
  1185. X                                 }
  1186. X                              }
  1187. X                           else {
  1188. X                              Image->red[index] = iff_colour_map[creg].Red;
  1189. X                              Image->green[index] = iff_colour_map[creg].Green;
  1190. X                              Image->blue[index] = iff_colour_map[creg].Blue;
  1191. X                              }
  1192. X
  1193. X                           mask >>= 1;
  1194. X                           if (mask == 0) {
  1195. X                              mask = 0x80;
  1196. X                              byte_index++;
  1197. X                              }
  1198. X                           }
  1199. X                        }
  1200. X
  1201. X                     free (row_bytes);
  1202. X                     fclose (f);
  1203. X                     return;
  1204. X         default:
  1205. X            for (i = 0 ; i < Chunk_Header.size ; i++)
  1206. X               if (getc(f) == EOF)
  1207. X                  iff_error();
  1208. X            break;
  1209. X         }
  1210. X      }
  1211. X   }
  1212. END_OF_FILE
  1213. if test 10876 -ne `wc -c <'src/iff.c'`; then
  1214.     echo shar: \"'src/iff.c'\" unpacked with wrong size!
  1215. fi
  1216. # end of 'src/iff.c'
  1217. fi
  1218. if test -f 'src/objects.c' -a "${1}" != "-c" ; then 
  1219.   echo shar: Will not clobber existing file \"'src/objects.c'\"
  1220. else
  1221. echo shar: Extracting \"'src/objects.c'\" \(11964 characters\)
  1222. sed "s/^X//" >'src/objects.c' <<'END_OF_FILE'
  1223. X/*****************************************************************************
  1224. X*
  1225. X*                                    objects.c
  1226. X*
  1227. X*   from DKBTrace (c) 1990  David Buck
  1228. X*
  1229. X*  This module implements the methods for objects and composite objects.
  1230. X*
  1231. X* This software is freely distributable. The source and/or object code may be
  1232. X* copied or uploaded to communications services so long as this notice remains
  1233. X* at the top of each file.  If any changes are made to the program, you must
  1234. X* clearly indicate in the documentation and in the programs startup message
  1235. X* who it was who made the changes. The documentation should also describe what
  1236. X* those changes were. This software may not be included in whole or in
  1237. X* part into any commercial package without the express written consent of the
  1238. X* author.  It may, however, be included in other public domain or freely
  1239. X* distributed software so long as the proper credit for the software is given.
  1240. X*
  1241. X* This software is provided as is without any guarantees or warranty. Although
  1242. X* the author has attempted to find and correct any bugs in the software, he
  1243. X* is not responsible for any damage caused by the use of the software.  The
  1244. X* author is under no obligation to provide service, corrections, or upgrades
  1245. X* to this package.
  1246. X*
  1247. X* Despite all the legal stuff above, if you do find bugs, I would like to hear
  1248. X* about them.  Also, if you have any comments or questions, you may contact me
  1249. X* at the following address:
  1250. X*
  1251. X*     David Buck
  1252. X*     22C Sonnet Cres.
  1253. X*     Nepean Ontario
  1254. X*     Canada, K2H 8W7
  1255. X*
  1256. X*  I can also be reached on the following bulleton boards:
  1257. X*
  1258. X*     ATX              (613) 526-4141
  1259. X*     OMX              (613) 731-3419
  1260. X*     Mystic           (613) 731-0088 or (613) 731-6698
  1261. X*
  1262. X*  Fidonet:   1:163/109.9
  1263. X*  Internet:  David_Buck@Carleton.CA
  1264. X*
  1265. X*  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  1266. X*
  1267. X*     Lattice BBS                      (708) 916-1200
  1268. X*     The Information Exchange BBS     (708) 945-5575
  1269. X*     Stillwaters BBS                  (708) 403-2826
  1270. X*
  1271. X*****************************************************************************/
  1272. X
  1273. X
  1274. X#include "frame.h"
  1275. X#include "vector.h"
  1276. X#include "dkbproto.h"
  1277. X
  1278. Xextern RAY *VP_Ray;
  1279. Xextern long Bounding_Region_Tests, Bounding_Region_Tests_Succeeded;
  1280. X
  1281. XMETHODS Composite_Methods =
  1282. X   { Object_Intersect, All_Composite_Intersections,
  1283. X     Inside_Composite_Object, NULL,
  1284. X     Copy_Composite_Object,
  1285. X     Translate_Composite_Object, Rotate_Composite_Object,
  1286. X     Scale_Composite_Object, Invert_Composite_Object};
  1287. X
  1288. XMETHODS Basic_Object_Methods =
  1289. X   { Object_Intersect, All_Object_Intersections,
  1290. X     Inside_Basic_Object, NULL,
  1291. X     Copy_Basic_Object,
  1292. X     Translate_Basic_Object, Rotate_Basic_Object,
  1293. X     Scale_Basic_Object, Invert_Basic_Object};
  1294. X
  1295. X
  1296. XINTERSECTION *Object_Intersect (Object, Ray)
  1297. X   OBJECT *Object;
  1298. X   RAY *Ray;
  1299. X   {
  1300. X   INTERSECTION *Local_Intersection, *Queue_Element;
  1301. X   PRIOQ *Depth_Queue;
  1302. X
  1303. X   Depth_Queue = pq_new (128);
  1304. X
  1305. X   if ((All_Intersections (Object, Ray, Depth_Queue))
  1306. X      && ((Queue_Element = pq_get_highest (Depth_Queue)) != NULL))
  1307. X      {
  1308. X      Local_Intersection = (INTERSECTION *) malloc(sizeof(INTERSECTION));
  1309. X      Local_Intersection -> Point = Queue_Element -> Point;
  1310. X      Local_Intersection -> Shape = Queue_Element -> Shape;
  1311. X      Local_Intersection -> Depth = Queue_Element -> Depth;
  1312. X      Local_Intersection -> Object = Queue_Element -> Object;
  1313. X      pq_free (Depth_Queue);
  1314. X      return (Local_Intersection);
  1315. X      }
  1316. X   else
  1317. X      {
  1318. X      pq_free (Depth_Queue);
  1319. X      return (NULL);
  1320. X      }
  1321. X   }
  1322. X
  1323. Xint All_Composite_Intersections (Object, Ray, Depth_Queue)
  1324. X   OBJECT *Object;
  1325. X   RAY *Ray;
  1326. X   PRIOQ *Depth_Queue;
  1327. X   {
  1328. X   register int Intersection_Found;
  1329. X   SHAPE *Bounding_Shape;
  1330. X   INTERSECTION *Local_Intersection;
  1331. X   OBJECT *Local_Object;
  1332. X
  1333. X   for (Bounding_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
  1334. X        Bounding_Shape != NULL ;
  1335. X        Bounding_Shape = Bounding_Shape -> Next_Object) {
  1336. X
  1337. X     Bounding_Region_Tests++;
  1338. X     if ((Local_Intersection = Intersection ((OBJECT *) Bounding_Shape, Ray)) != NULL)
  1339. X        free (Local_Intersection);
  1340. X     else
  1341. X        if (!Inside (&Ray -> Initial, (OBJECT *) Bounding_Shape))
  1342. X           return (FALSE);
  1343. X     Bounding_Region_Tests_Succeeded++;
  1344. X     }
  1345. X
  1346. X   Intersection_Found = FALSE;
  1347. X   for (Local_Object = ((COMPOSITE *) Object) -> Objects ;
  1348. X        Local_Object != NULL ;
  1349. X        Local_Object = Local_Object -> Next_Object)
  1350. X
  1351. X      if (All_Intersections (Local_Object, Ray, Depth_Queue))
  1352. X         Intersection_Found = TRUE;
  1353. X
  1354. X   return (Intersection_Found);
  1355. X   }
  1356. X
  1357. Xint All_Object_Intersections (Object, Ray, Depth_Queue)
  1358. X   OBJECT *Object;
  1359. X   RAY *Ray;
  1360. X   PRIOQ *Depth_Queue;
  1361. X   {
  1362. X   INTERSECTION *Local_Intersection;
  1363. X   SHAPE *Bounding_Shape;
  1364. X
  1365. X   for (Bounding_Shape = Object -> Bounding_Shapes ;
  1366. X        Bounding_Shape != NULL ;
  1367. X        Bounding_Shape = Bounding_Shape -> Next_Object) {
  1368. X
  1369. X      Bounding_Region_Tests++;
  1370. X      if ((Local_Intersection = Intersection ((OBJECT *) Bounding_Shape, Ray)) != NULL)
  1371. X         free (Local_Intersection);
  1372. X      else
  1373. X         if (!Inside (&Ray -> Initial, (OBJECT *) Bounding_Shape))
  1374. X            return (FALSE);
  1375. X      Bounding_Region_Tests_Succeeded++;
  1376. X      }
  1377. X
  1378. X   All_Intersections ((OBJECT *) Object -> Shape, Ray, Depth_Queue);
  1379. X
  1380. X   if (pq_is_empty (Depth_Queue))
  1381. X     return (FALSE);
  1382. X   return (TRUE);
  1383. X   }
  1384. X
  1385. X
  1386. Xint Inside_Basic_Object (Point, Object)
  1387. X   VECTOR *Point;
  1388. X   OBJECT *Object;
  1389. X   {
  1390. X   SHAPE *Bounding_Shape;
  1391. X
  1392. X   for (Bounding_Shape = Object -> Bounding_Shapes ;
  1393. X        Bounding_Shape != NULL ;
  1394. X        Bounding_Shape = Bounding_Shape -> Next_Object)
  1395. X
  1396. X      if (!Inside (Point, (OBJECT *) Bounding_Shape))
  1397. X         return (FALSE);
  1398. X
  1399. X   if (Inside (Point, (OBJECT *) Object -> Shape))
  1400. X      return (TRUE);
  1401. X   return (FALSE);
  1402. X   }
  1403. X
  1404. Xint Inside_Composite_Object (Point, Object)
  1405. X   VECTOR *Point;
  1406. X   OBJECT *Object;
  1407. X   {
  1408. X   SHAPE *Bounding_Shape;
  1409. X   OBJECT *Local_Object;
  1410. X
  1411. X   for (Bounding_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
  1412. X        Bounding_Shape != NULL ;
  1413. X        Bounding_Shape = Bounding_Shape -> Next_Object)
  1414. X
  1415. X     if (!Inside (Point, (OBJECT *) Bounding_Shape))
  1416. X       return (FALSE);
  1417. X
  1418. X   for (Local_Object = ((COMPOSITE *) Object) -> Objects ;
  1419. X        Local_Object != NULL ;
  1420. X        Local_Object = Local_Object -> Next_Object)
  1421. X
  1422. X      if (Inside (Point, Local_Object))
  1423. X         return (TRUE);
  1424. X
  1425. X   return (FALSE);
  1426. X   }
  1427. X
  1428. Xvoid *Copy_Basic_Object (Object)
  1429. X   OBJECT *Object;
  1430. X   {
  1431. X   SHAPE *Local_Shape, *Copied_Shape;
  1432. X   OBJECT *New_Object;
  1433. X
  1434. X   New_Object = Get_Object();
  1435. X   *New_Object = *Object;
  1436. X   New_Object -> Next_Object = NULL;
  1437. X   New_Object -> Bounding_Shapes = NULL;
  1438. X   for (Local_Shape = Object -> Bounding_Shapes ;
  1439. X        Local_Shape != NULL ;
  1440. X        Local_Shape = Local_Shape -> Next_Object) {
  1441. X
  1442. X      Copied_Shape = (SHAPE *) Copy((OBJECT *) Local_Shape);
  1443. X      Link ((OBJECT *) Copied_Shape,
  1444. X            (OBJECT **) &(Copied_Shape -> Next_Object),
  1445. X            (OBJECT **) &(New_Object -> Bounding_Shapes));
  1446. X      Copied_Shape -> Parent_Object = Object;
  1447. X      }
  1448. X
  1449. X   New_Object -> Shape = (SHAPE *) Copy((OBJECT *) Object -> Shape);
  1450. X   Object -> Shape -> Parent_Object = Object;
  1451. X   return (New_Object);
  1452. X   }
  1453. X
  1454. Xvoid *Copy_Composite_Object (Object)
  1455. X   OBJECT *Object;
  1456. X   {
  1457. X   COMPOSITE *New_Object;
  1458. X   SHAPE *Local_Shape;
  1459. X   OBJECT *Local_Object, *Copied_Object;
  1460. X
  1461. X   New_Object = Get_Composite_Object();
  1462. X   *New_Object = *((COMPOSITE *) Object);
  1463. X   New_Object -> Next_Object = NULL;
  1464. X   New_Object -> Objects = NULL;
  1465. X   for (Local_Object = ((COMPOSITE *) Object) -> Objects;
  1466. X        Local_Object != NULL ;
  1467. X        Local_Object = Local_Object -> Next_Object) {
  1468. X
  1469. X      Copied_Object = (OBJECT *) Copy(Local_Object);
  1470. X      Link (Copied_Object,
  1471. X            &(Copied_Object -> Next_Object),
  1472. X            &(New_Object -> Objects));
  1473. X      }
  1474. X
  1475. X   New_Object -> Bounding_Shapes = NULL;
  1476. X   for (Local_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes;
  1477. X        Local_Shape != NULL ;
  1478. X        Local_Shape = Local_Shape -> Next_Object) {
  1479. X
  1480. X      Copied_Object = (OBJECT *) Copy((OBJECT *) Local_Shape);
  1481. X      Link (Copied_Object,
  1482. X            &(Copied_Object -> Next_Object),
  1483. X            (OBJECT **) &(New_Object -> Bounding_Shapes));
  1484. X      }
  1485. X   return (New_Object);
  1486. X   }
  1487. X
  1488. Xvoid Translate_Basic_Object (Object, Vector)
  1489. X   OBJECT *Object;
  1490. X   VECTOR *Vector;
  1491. X   {
  1492. X   SHAPE *Local_Shape;
  1493. X
  1494. X   for (Local_Shape = Object -> Bounding_Shapes ;
  1495. X        Local_Shape != NULL ;
  1496. X        Local_Shape = Local_Shape -> Next_Object)
  1497. X
  1498. X      Translate ((OBJECT *) Local_Shape, Vector);
  1499. X
  1500. X   Translate ((OBJECT *) Object -> Shape, Vector);
  1501. X
  1502. X   VAdd (Object -> Object_Center, Object -> Object_Center, *Vector);
  1503. X   }
  1504. X
  1505. Xvoid Rotate_Basic_Object (Object, Vector)
  1506. X   OBJECT *Object;
  1507. X   VECTOR *Vector;
  1508. X   {
  1509. X   SHAPE *Local_Shape;
  1510. X   TRANSFORMATION Transformation;
  1511. X
  1512. X   for (Local_Shape = Object -> Bounding_Shapes ;
  1513. X        Local_Shape != NULL ;
  1514. X        Local_Shape = Local_Shape -> Next_Object)
  1515. X
  1516. X      Rotate ((OBJECT *) Local_Shape, Vector);
  1517. X
  1518. X   Rotate ((OBJECT *) Object -> Shape, Vector);
  1519. X   Get_Rotation_Transformation (&Transformation, Vector);
  1520. X   MTransformVector (&Object->Object_Center,
  1521. X                     &Object->Object_Center, &Transformation);
  1522. X   }
  1523. X
  1524. Xvoid Scale_Basic_Object (Object, Vector)
  1525. X   OBJECT *Object;
  1526. X   VECTOR *Vector;
  1527. X   {
  1528. X   SHAPE *Local_Shape;
  1529. X
  1530. X   for (Local_Shape = Object -> Bounding_Shapes ;
  1531. X        Local_Shape != NULL ;
  1532. X        Local_Shape = Local_Shape -> Next_Object)
  1533. X
  1534. X      Scale ((OBJECT *) Local_Shape, Vector);
  1535. X
  1536. X   Scale ((OBJECT *) Object -> Shape, Vector);
  1537. X
  1538. X   VEvaluate (Object -> Object_Center, Object -> Object_Center, *Vector);
  1539. X   }
  1540. X
  1541. Xvoid Translate_Composite_Object (Object, Vector)
  1542. X   OBJECT *Object;
  1543. X   VECTOR *Vector;
  1544. X   {
  1545. X   OBJECT *Local_Object;
  1546. X   SHAPE *Local_Shape;
  1547. X
  1548. X   for (Local_Object = ((COMPOSITE *) Object) -> Objects;
  1549. X        Local_Object != NULL ;
  1550. X        Local_Object = Local_Object -> Next_Object)
  1551. X      Translate (Local_Object, Vector);   
  1552. X
  1553. X   for (Local_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
  1554. X        Local_Shape != NULL ;
  1555. X        Local_Shape = Local_Shape -> Next_Object)
  1556. X
  1557. X      Translate ((OBJECT *) Local_Shape, Vector);
  1558. X   }
  1559. X
  1560. Xvoid Rotate_Composite_Object (Object, Vector)
  1561. X   OBJECT *Object;
  1562. X   VECTOR *Vector;
  1563. X   {
  1564. X   OBJECT *Local_Object;
  1565. X   SHAPE *Local_Shape;
  1566. X
  1567. X   for (Local_Object = ((COMPOSITE *) Object) -> Objects;
  1568. X        Local_Object != NULL ;
  1569. X        Local_Object = Local_Object -> Next_Object)
  1570. X      Rotate (Local_Object, Vector);   
  1571. X
  1572. X   for (Local_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
  1573. X        Local_Shape != NULL ;
  1574. X        Local_Shape = Local_Shape -> Next_Object)
  1575. X
  1576. X      Rotate ((OBJECT *) Local_Shape, Vector);
  1577. X   }
  1578. X
  1579. Xvoid Scale_Composite_Object (Object, Vector)
  1580. X   OBJECT *Object;
  1581. X   VECTOR *Vector;
  1582. X   {
  1583. X   OBJECT *Local_Object;
  1584. X   SHAPE *Local_Shape;
  1585. X
  1586. X   for (Local_Object = ((COMPOSITE *) Object) -> Objects;
  1587. X        Local_Object != NULL ;
  1588. X        Local_Object = Local_Object -> Next_Object)
  1589. X      Scale (Local_Object, Vector);   
  1590. X
  1591. X   for (Local_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
  1592. X        Local_Shape != NULL ;
  1593. X        Local_Shape = Local_Shape -> Next_Object)
  1594. X
  1595. X      Scale ((OBJECT *) Local_Shape, Vector);
  1596. X   }
  1597. X
  1598. X
  1599. Xvoid Invert_Basic_Object (Object)
  1600. X   OBJECT *Object;
  1601. X   {
  1602. X   SHAPE *Local_Shape;
  1603. X
  1604. X   for (Local_Shape = Object -> Bounding_Shapes ;
  1605. X        Local_Shape != NULL ;
  1606. X        Local_Shape = Local_Shape -> Next_Object)
  1607. X
  1608. X      Invert ((OBJECT *) Local_Shape);
  1609. X   Invert ((OBJECT *) Object -> Shape);
  1610. X   }
  1611. X
  1612. Xvoid Invert_Composite_Object (Object)
  1613. X   OBJECT *Object;
  1614. X   {
  1615. X   OBJECT *Local_Object;
  1616. X   SHAPE *Local_Shape;
  1617. X
  1618. X   for (Local_Object = ((COMPOSITE *)Object) -> Objects;
  1619. X        Local_Object != NULL ;
  1620. X        Local_Object = Local_Object -> Next_Object)
  1621. X
  1622. X      Invert (Local_Object);   
  1623. X
  1624. X   for (Local_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
  1625. X        Local_Shape != NULL ;
  1626. X        Local_Shape = Local_Shape -> Next_Object)
  1627. X
  1628. X      Invert ((OBJECT *) Local_Shape);
  1629. X   }
  1630. END_OF_FILE
  1631. if test 11964 -ne `wc -c <'src/objects.c'`; then
  1632.     echo shar: \"'src/objects.c'\" unpacked with wrong size!
  1633. fi
  1634. # end of 'src/objects.c'
  1635. fi
  1636. if test -f 'src/quadrics.c' -a "${1}" != "-c" ; then 
  1637.   echo shar: Will not clobber existing file \"'src/quadrics.c'\"
  1638. else
  1639. echo shar: Extracting \"'src/quadrics.c'\" \(11498 characters\)
  1640. sed "s/^X//" >'src/quadrics.c' <<'END_OF_FILE'
  1641. X/*****************************************************************************
  1642. X*
  1643. X*                                   quadrics.c
  1644. X*
  1645. X*   from DKBTrace (c) 1990  David Buck
  1646. X*
  1647. X*  This module implements the code for the quadric shape primitive.
  1648. X*
  1649. X* This software is freely distributable. The source and/or object code may be
  1650. X* copied or uploaded to communications services so long as this notice remains
  1651. X* at the top of each file.  If any changes are made to the program, you must
  1652. X* clearly indicate in the documentation and in the programs startup message
  1653. X* who it was who made the changes. The documentation should also describe what
  1654. X* those changes were. This software may not be included in whole or in
  1655. X* part into any commercial package without the express written consent of the
  1656. X* author.  It may, however, be included in other public domain or freely
  1657. X* distributed software so long as the proper credit for the software is given.
  1658. X*
  1659. X* This software is provided as is without any guarantees or warranty. Although
  1660. X* the author has attempted to find and correct any bugs in the software, he
  1661. X* is not responsible for any damage caused by the use of the software.  The
  1662. X* author is under no obligation to provide service, corrections, or upgrades
  1663. X* to this package.
  1664. X*
  1665. X* Despite all the legal stuff above, if you do find bugs, I would like to hear
  1666. X* about them.  Also, if you have any comments or questions, you may contact me
  1667. X* at the following address:
  1668. X*
  1669. X*     David Buck
  1670. X*     22C Sonnet Cres.
  1671. X*     Nepean Ontario
  1672. X*     Canada, K2H 8W7
  1673. X*
  1674. X*  I can also be reached on the following bulleton boards:
  1675. X*
  1676. X*     ATX              (613) 526-4141
  1677. X*     OMX              (613) 731-3419
  1678. X*     Mystic           (613) 731-0088 or (613) 731-6698
  1679. X*
  1680. X*  Fidonet:   1:163/109.9
  1681. X*  Internet:  David_Buck@Carleton.CA
  1682. X*
  1683. X*  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  1684. X*
  1685. X*     Lattice BBS                      (708) 916-1200
  1686. X*     The Information Exchange BBS     (708) 945-5575
  1687. X*     Stillwaters BBS                  (708) 403-2826
  1688. X*
  1689. X*****************************************************************************/
  1690. X
  1691. X
  1692. X#include "frame.h"
  1693. X#include "vector.h"
  1694. X#include "dkbproto.h"
  1695. X
  1696. XMETHODS Quadric_Methods =
  1697. X   { Object_Intersect, All_Quadric_Intersections,
  1698. X     Inside_Quadric, Quadric_Normal,
  1699. X     Copy_Quadric,
  1700. X     Translate_Quadric, Rotate_Quadric,
  1701. X     Scale_Quadric, Invert_Quadric};
  1702. X
  1703. Xextern RAY *VP_Ray;
  1704. Xextern long Ray_Quadric_Tests, Ray_Quadric_Tests_Succeeded;
  1705. X
  1706. Xint All_Quadric_Intersections (Object, Ray, Depth_Queue)
  1707. X   OBJECT *Object;
  1708. X   RAY *Ray;
  1709. X   PRIOQ *Depth_Queue;
  1710. X   {
  1711. X   QUADRIC *Shape = (QUADRIC *) Object;
  1712. X   DBL Depth1, Depth2;
  1713. X   VECTOR Intersection_Point;
  1714. X   INTERSECTION Local_Element;
  1715. X   register int Intersection_Found;
  1716. X
  1717. X   Intersection_Found = FALSE;
  1718. X   if (Intersect_Quadric (Ray, Shape, &Depth1, &Depth2))
  1719. X      {
  1720. X      Local_Element.Depth = Depth1;
  1721. X      Local_Element.Object = Shape -> Parent_Object;
  1722. X      VScale (Intersection_Point, Ray -> Direction, Depth1);
  1723. X      VAdd (Intersection_Point, Intersection_Point, Ray -> Initial);
  1724. X      Local_Element.Point = Intersection_Point;
  1725. X      Local_Element.Shape = (SHAPE *)Shape;
  1726. X      pq_add (Depth_Queue, &Local_Element);
  1727. X      Intersection_Found = TRUE;
  1728. X
  1729. X      if (Depth2 != Depth1)
  1730. X         {
  1731. X         Local_Element.Depth = Depth2;
  1732. X         Local_Element.Object = Shape -> Parent_Object;
  1733. X         VScale (Intersection_Point, Ray -> Direction, Depth2);
  1734. X         VAdd (Intersection_Point, Intersection_Point, Ray -> Initial);
  1735. X         Local_Element.Point = Intersection_Point;
  1736. X         Local_Element.Shape = (SHAPE *) Shape;
  1737. X         pq_add (Depth_Queue, &Local_Element);
  1738. X         Intersection_Found = TRUE;
  1739. X         }
  1740. X      }
  1741. X   return (Intersection_Found);
  1742. X   }
  1743. X
  1744. Xint Intersect_Quadric (Ray, Shape, Depth1, Depth2)
  1745. X   RAY *Ray;
  1746. X   QUADRIC *Shape;
  1747. X   DBL *Depth1, *Depth2;
  1748. X   {
  1749. X   register DBL Square_Term, Linear_Term, Constant_Term, Temp_Term;
  1750. X   register DBL Determinant, Determinant_2, A2, BMinus;
  1751. X
  1752. X   Ray_Quadric_Tests++;
  1753. X   if (!Ray->Quadric_Constants_Cached)
  1754. X      Make_Ray(Ray);
  1755. X
  1756. X   if (Shape -> Non_Zero_Square_Term)
  1757. X      {
  1758. X      VDot (Square_Term, Shape -> Object_2_Terms, Ray -> Direction_2);
  1759. X      VDot (Temp_Term, Shape -> Object_Mixed_Terms, Ray -> Mixed_Dir_Dir);
  1760. X      Square_Term += Temp_Term;
  1761. X      }
  1762. X   else
  1763. X      Square_Term = 0.0;
  1764. X
  1765. X   VDot (Linear_Term, Shape -> Object_2_Terms, Ray -> Initial_Direction);
  1766. X   Linear_Term *= 2.0;
  1767. X   VDot (Temp_Term, Shape -> Object_Terms, Ray -> Direction);
  1768. X   Linear_Term += Temp_Term;
  1769. X   VDot (Temp_Term, Shape -> Object_Mixed_Terms, Ray -> Mixed_Init_Dir);
  1770. X   Linear_Term += Temp_Term;
  1771. X
  1772. X   if (Ray == VP_Ray)
  1773. X      if (!Shape -> Constant_Cached)
  1774. X         {
  1775. X         VDot (Constant_Term, Shape -> Object_2_Terms, Ray -> Initial_2);
  1776. X         VDot (Temp_Term, Shape -> Object_Terms, Ray -> Initial);
  1777. X         Constant_Term +=  Temp_Term + Shape -> Object_Constant;
  1778. X         Shape -> Object_VP_Constant = Constant_Term;
  1779. X         Shape -> Constant_Cached = TRUE;
  1780. X         }
  1781. X      else
  1782. X         Constant_Term = Shape -> Object_VP_Constant;
  1783. X   else
  1784. X      {
  1785. X      VDot (Constant_Term, Shape -> Object_2_Terms, Ray -> Initial_2);
  1786. X      VDot (Temp_Term, Shape -> Object_Terms, Ray -> Initial);
  1787. X      Constant_Term += Temp_Term + Shape -> Object_Constant;
  1788. X      }
  1789. X
  1790. X   VDot (Temp_Term, Shape -> Object_Mixed_Terms, 
  1791. X         Ray -> Mixed_Initial_Initial);
  1792. X   Constant_Term += Temp_Term;
  1793. X
  1794. X   if (Square_Term != 0.0)
  1795. X      {
  1796. X  /* The equation is quadratic - find its roots */
  1797. X
  1798. X      Determinant_2 = Linear_Term * Linear_Term - 4.0 * Square_Term * Constant_Term;
  1799. X
  1800. X      if (Determinant_2 < 0.0)
  1801. X         return (FALSE);
  1802. X
  1803. X      Determinant = sqrt (Determinant_2);
  1804. X      A2 = Square_Term * 2.0;
  1805. X      BMinus = Linear_Term * -1.0;
  1806. X
  1807. X      *Depth1 = (BMinus + Determinant) / A2;
  1808. X      *Depth2 = (BMinus - Determinant) / A2;
  1809. X      }
  1810. X   else
  1811. X      {
  1812. X    /* There are no quadratic terms.  Solve the linear equation instead. */
  1813. X      if (Linear_Term == 0.0)
  1814. X         return (FALSE);
  1815. X
  1816. X      *Depth1 = Constant_Term * -1.0 / Linear_Term;
  1817. X      *Depth2 = *Depth1;
  1818. X      }
  1819. X
  1820. X   if ((*Depth1 < Small_Tolerance) || (*Depth1 > Max_Distance))
  1821. X      if ((*Depth2 < Small_Tolerance) || (*Depth2 > Max_Distance))
  1822. X         return (FALSE);
  1823. X      else
  1824. X         *Depth1 = *Depth2;
  1825. X   else
  1826. X      if ((*Depth2 < Small_Tolerance) || (*Depth2 > Max_Distance))
  1827. X        *Depth2 = *Depth1;
  1828. X
  1829. X   Ray_Quadric_Tests_Succeeded++;
  1830. X   return (TRUE);
  1831. X   }
  1832. X
  1833. Xint Inside_Quadric (Point, Object)
  1834. X   VECTOR *Point;
  1835. X   OBJECT *Object;
  1836. X   {
  1837. X   QUADRIC *Shape = (QUADRIC *) Object;
  1838. X   VECTOR New_Point;
  1839. X   register DBL Result, Linear_Term, Square_Term;
  1840. X
  1841. X   VDot (Linear_Term, *Point, Shape -> Object_Terms);
  1842. X   Result = Linear_Term + Shape -> Object_Constant;
  1843. X   VSquareTerms (New_Point, *Point);
  1844. X   VDot (Square_Term, New_Point, Shape -> Object_2_Terms);
  1845. X   Result += Square_Term;
  1846. X   Result += Shape -> Object_Mixed_Terms.x * (Point -> x) * (Point -> y)
  1847. X            + Shape -> Object_Mixed_Terms.y * (Point -> x) * (Point -> z)
  1848. X            + Shape -> Object_Mixed_Terms.z * (Point -> y) * (Point -> z);
  1849. X
  1850. X   if (Result < Small_Tolerance)
  1851. X      return (TRUE);
  1852. X
  1853. X   return (FALSE);
  1854. X   }
  1855. X
  1856. Xvoid Quadric_Normal (Result, Object, Intersection_Point)
  1857. X   VECTOR *Result, *Intersection_Point;
  1858. X   OBJECT *Object;
  1859. X   {
  1860. X   QUADRIC *Intersection_Shape = (QUADRIC *) Object;
  1861. X   VECTOR Derivative_Linear;
  1862. X
  1863. X   VScale (Derivative_Linear, Intersection_Shape -> Object_2_Terms, 2.0);
  1864. X   VEvaluate (*Result, Derivative_Linear, *Intersection_Point);
  1865. X   VAdd (*Result, *Result, Intersection_Shape -> Object_Terms);
  1866. X
  1867. X   Result -> x += 
  1868. X         Intersection_Shape -> Object_Mixed_Terms.x * Intersection_Point -> y +
  1869. X         Intersection_Shape -> Object_Mixed_Terms.y * Intersection_Point -> z;
  1870. X
  1871. X
  1872. X   Result -> y +=
  1873. X         Intersection_Shape -> Object_Mixed_Terms.x * Intersection_Point -> x +
  1874. X         Intersection_Shape -> Object_Mixed_Terms.z * Intersection_Point -> z;
  1875. X
  1876. X   Result -> z +=
  1877. X         Intersection_Shape -> Object_Mixed_Terms.y * Intersection_Point -> x +
  1878. X         Intersection_Shape -> Object_Mixed_Terms.z * Intersection_Point -> y;
  1879. X
  1880. X   VNormalize (*Result, *Result);
  1881. X   Perturb_Normal (Result, Intersection_Shape -> Parent_Object,
  1882. X                   Intersection_Point, Result);
  1883. X   }
  1884. X
  1885. Xvoid *Copy_Quadric (Object)
  1886. X   OBJECT *Object;
  1887. X   {
  1888. X   QUADRIC *New_Shape;
  1889. X
  1890. X   New_Shape = Get_Quadric_Shape ();
  1891. X   *New_Shape = *((QUADRIC *) Object);
  1892. X   New_Shape -> Next_Object = NULL;
  1893. X   return (New_Shape);
  1894. X   }
  1895. X
  1896. Xvoid Transform_Quadric (Shape, Transformation)
  1897. X   QUADRIC *Shape;
  1898. X   TRANSFORMATION *Transformation;
  1899. X   {
  1900. X   MATRIX Quadric_Matrix, Transform_Transposed;
  1901. X
  1902. X   Quadric_To_Matrix (Shape, (MATRIX *) &Quadric_Matrix[0][0]);
  1903. X   MTimes ((MATRIX *) &Quadric_Matrix[0][0], (MATRIX *) &(Transformation -> inverse[0][0]), (MATRIX *) &Quadric_Matrix[0][0]);
  1904. X   MTranspose ((MATRIX *) &Transform_Transposed[0][0], (MATRIX *) &(Transformation -> inverse[0][0]));
  1905. X   MTimes ((MATRIX *) &Quadric_Matrix[0][0], (MATRIX *) &Quadric_Matrix[0][0], (MATRIX *) &Transform_Transposed[0][0]);
  1906. X   Matrix_To_Quadric ((MATRIX *) &Quadric_Matrix[0][0], Shape);
  1907. X   }
  1908. X
  1909. Xvoid Quadric_To_Matrix (Quadric, Matrix)
  1910. X   QUADRIC *Quadric;
  1911. X   MATRIX *Matrix;
  1912. X   {
  1913. X   MZero (Matrix);
  1914. X   (*Matrix)[0][0] = Quadric -> Object_2_Terms.x;
  1915. X   (*Matrix)[1][1] = Quadric -> Object_2_Terms.y;
  1916. X   (*Matrix)[2][2] = Quadric -> Object_2_Terms.z;
  1917. X   (*Matrix)[0][1] = Quadric -> Object_Mixed_Terms.x;
  1918. X   (*Matrix)[0][2] = Quadric -> Object_Mixed_Terms.y;
  1919. X   (*Matrix)[0][3] = Quadric -> Object_Terms.x;
  1920. X   (*Matrix)[1][2] = Quadric -> Object_Mixed_Terms.z;
  1921. X   (*Matrix)[1][3] = Quadric -> Object_Terms.y;
  1922. X   (*Matrix)[2][3] = Quadric -> Object_Terms.z;
  1923. X   (*Matrix)[3][3] = Quadric -> Object_Constant;
  1924. X   }
  1925. X
  1926. Xvoid Matrix_To_Quadric (Matrix, Quadric)
  1927. X   MATRIX *Matrix;
  1928. X   QUADRIC *Quadric;
  1929. X   {
  1930. X   Quadric -> Object_2_Terms.x = (*Matrix)[0][0];
  1931. X   Quadric -> Object_2_Terms.y = (*Matrix)[1][1];
  1932. X   Quadric -> Object_2_Terms.z = (*Matrix)[2][2];
  1933. X   Quadric -> Object_Mixed_Terms.x = (*Matrix)[0][1] + (*Matrix)[1][0];
  1934. X   Quadric -> Object_Mixed_Terms.y = (*Matrix)[0][2] + (*Matrix)[2][0];
  1935. X   Quadric -> Object_Terms.x = (*Matrix)[0][3] + (*Matrix)[3][0];
  1936. X   Quadric -> Object_Mixed_Terms.z = (*Matrix)[1][2] + (*Matrix)[2][1];
  1937. X   Quadric -> Object_Terms.y = (*Matrix)[1][3] + (*Matrix)[3][1];
  1938. X   Quadric -> Object_Terms.z = (*Matrix)[2][3] + (*Matrix)[3][2];
  1939. X   Quadric -> Object_Constant = (*Matrix)[3][3];
  1940. X   }
  1941. X
  1942. Xvoid Translate_Quadric (Object, Vector)
  1943. X   OBJECT *Object;
  1944. X   VECTOR *Vector;
  1945. X   {
  1946. X   TRANSFORMATION Transformation;
  1947. X
  1948. X   Get_Translation_Transformation (&Transformation, Vector);
  1949. X   Transform_Quadric ((QUADRIC *) Object, &Transformation);
  1950. X   }
  1951. X
  1952. Xvoid Rotate_Quadric (Object, Vector)
  1953. X   OBJECT *Object;
  1954. X   VECTOR *Vector;
  1955. X   {
  1956. X   TRANSFORMATION Transformation;
  1957. X
  1958. X   Get_Rotation_Transformation (&Transformation, Vector);
  1959. X   Transform_Quadric ((QUADRIC *) Object, &Transformation);
  1960. X   }
  1961. X
  1962. Xvoid Scale_Quadric (Object, Vector)
  1963. X   OBJECT *Object;
  1964. X   VECTOR *Vector;
  1965. X   {
  1966. X   TRANSFORMATION Transformation;
  1967. X
  1968. X   Get_Scaling_Transformation (&Transformation, Vector);
  1969. X   Transform_Quadric ((QUADRIC *) Object, &Transformation);
  1970. X   }
  1971. X
  1972. Xvoid Invert_Quadric (Object)
  1973. X   OBJECT *Object;
  1974. X   {
  1975. X   QUADRIC *Shape = (QUADRIC *) Object;
  1976. X
  1977. X   VScale (Shape -> Object_2_Terms, Shape -> Object_2_Terms, -1.0);
  1978. X   VScale (Shape -> Object_Mixed_Terms, Shape -> Object_Mixed_Terms, -1.0);
  1979. X   VScale (Shape -> Object_Terms, Shape -> Object_Terms, -1.0);
  1980. X   Shape -> Object_Constant *= -1.0;
  1981. X   }
  1982. END_OF_FILE
  1983. if test 11498 -ne `wc -c <'src/quadrics.c'`; then
  1984.     echo shar: \"'src/quadrics.c'\" unpacked with wrong size!
  1985. fi
  1986. # end of 'src/quadrics.c'
  1987. fi
  1988. echo shar: End of archive 4 \(of 10\).
  1989. cp /dev/null ark4isdone
  1990. MISSING=""
  1991. for I in 1 2 3 4 5 6 7 8 9 10 ; do
  1992.     if test ! -f ark${I}isdone ; then
  1993.     MISSING="${MISSING} ${I}"
  1994.     fi
  1995. done
  1996. if test "${MISSING}" = "" ; then
  1997.     echo You have unpacked all 10 archives.
  1998.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1999. else
  2000.     echo You still need to unpack the following archives:
  2001.     echo "        " ${MISSING}
  2002. fi
  2003. ##  End of shell archive.
  2004. exit 0
  2005. -- 
  2006. Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
  2007. Mail comments to the moderator at <amiga-request@uunet.uu.net>.
  2008. Post requests for sources, and general discussion to comp.sys.amiga.
  2009.